package InvocationHandler;

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class PersonDynamicJDKProxyHandler implements InvocationHandler {

	private final Object targetObject;

	public PersonDynamicJDKProxyHandler(Object object) {
		this.targetObject = object;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		if (method.getName().equals("eat")) {
			System.out.println("Wash hands before eating");
			method.invoke(targetObject, args);
			System.out.println("Finish eating");
		} else {
			System.out.println("Taking off clothes!");
			method.invoke(targetObject, args);
			System.out.println("Dreaming~~~!");
		}
		return null;
	}

	public static void main(String[] args) {
		Person person = new Person();
		PersonDynamicJDKProxyHandler handler = new PersonDynamicJDKProxyHandler(person);
		Sleepable proxy = (Sleepable) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass()
				.getInterfaces(), handler);

		generateProxyClassFile();

		proxy.eat();
		proxy.sleep();
	}

	private static void generateProxyClassFile() {
		byte[] classFile = sun.misc.ProxyGenerator.generateProxyClass("$MyProxy", Person.class.getInterfaces());

		FileOutputStream out = null;
		String path = "E:/workSpace/ThinkInJavaTest/bin/InvocationHandler$MyProxy.class";
		try {
			out = new FileOutputStream(path);
			out.write(classFile);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
